#include "stdafx.h"
#include "Game.h"
#include "..\..\EdgeGraphics\GraphicsManager.h"
#include "..\..\EdgeGameCore\BaseGameComponent.h"
#include "..\..\EdgeGameCore\StateMachine.h"
#include "..\..\EdgeGraphics\Camera.h"
#include "State Machine\GameplayState.h"
#include "..\..\EdgeControls\Input.h"
#include "..\..\EdgeMath\VectorHelper.h"
#include "..\..\EdgeMath\Vectors.h" 
#include "..\..\EdgeGraphics\Fonts.h" 
#include "..\..\EdgeGraphics\BitmapFont.h" 
#include "..\..\EdgeGraphics\HUD.h"
#include "..\..\EdgeGameCore\SettingsManager.h"
#include "..\..\EdgeGameCore\Console.h"
#include "..\..\EdgeGameCore\Particles\Particle.h"
#include "..\..\EdgeContent\ContentManager.h"
#include "..\..\EdgeGameCore\Particles\ParticleEmitter.h"
#include "..\..\EdgeMath\Math.h"
#include "..\..\EdgeGameCore\Particles\ParticleSystem.h"
#include "..\..\EdgeGameCore\Particles\ParticleEffector.h"
#include "..\..\EdgeGameCore\World\WorldEvents.h"
#include "../../EdgeGameCore/Objects/Player/Player.h"
#include "../../EdgeGraphics/RenderTargetManager.h"
#include "../../EdgeUtil/MemoryManager.h"
using namespace VectorHelper;

/*static*/ Game* Game::instance = nullptr;

Game::Game(HWND hwnd, const char* exePath)
{
	this->hwnd = hwnd;
	// inilitize state machine
	sMachine = new StateMachine;

		
	// inilitize settings
	SettingsManager* pSettings = SettingsManager::GetInstance();
	int scr_width = pSettings->getSetting("ScreenWidth")._int;
	int scr_height = pSettings->getSetting("ScreenHeight")._int;
	float masterVolume = pSettings->getSetting("MasterVolume")._float;
	// Inilitize graphics
	GraphicsManager* pGraphics = GraphicsManager::GetInstance();
	//RenderTargetManager::getInstance()->SetRenderTarget(pGraphics->getBackBuffer(), 0);
	//RenderTargetManager::getInstance()->Apply();
	// inilitize the EVENTS OF THE ENTIRE WORLD!!
	WorldEvents::Init();
	// Inilitize fonts
	Fonts::GetInstance();
	// inilitize content
	ContentManager::Init(exePath);
	// inilitize Audio
	AudioManager::GetInstance()->setMasterVolume(masterVolume);
	//////////////////////////////////////////
#pragma region setup rasterizer state
	ID3D11RasterizerState* rsState;

	D3D11_RASTERIZER_DESC rs_desc;
	ZeroMemory(&rs_desc, sizeof(D3D11_RASTERIZER_DESC));

	rs_desc.AntialiasedLineEnable = false;
	rs_desc.CullMode = D3D11_CULL_BACK;
	rs_desc.FillMode = D3D11_FILL_SOLID;
	rs_desc.MultisampleEnable = true;
	rs_desc.ScissorEnable = true;
	rs_desc.FrontCounterClockwise = true;
	pGraphics->getDevice()->CreateRasterizerState(&rs_desc, &rsState);
	pGraphics->setRasterizerState(rsState);

#pragma endregion


	/*Setup state machine*/
	GameplayState* gameplay_state = GameplayState::GetInstance();
	sMachine->setCurrentState(gameplay_state);
}

/*virtual*/ Game::~Game(void)
{
	delete sMachine;
	GameplayState::GetInstance()->Release();
	GraphicsManager::ShutDown();
	WorldEvents::Shutdown();
	ContentManager::Shutdown();
	Input::Shutdown();
}

/*virtual*/ void Game::Update(float dt) /*override*/
{
	Input::GetInstance()->BeginUpdate();
	//delta_t++;
	// update the current game state, if there is one
	if (sMachine->getCurrentState())
		sMachine->getCurrentState()->Update(dt);

	// update the command console
	Console::GetInstance()->Update(dt);
	// update input buffer
	AudioManager::GetInstance()->Update();
	Input::GetInstance()->EndUpdate();
}

/*virtual*/ void Game::Draw(void) /*override*/
{
	GraphicsManager* pGraphics = GraphicsManager::GetInstance();
	RenderTargetManager* pRtm = RenderTargetManager::getInstance();
	if (!Console::GetInstance()->isVisible())
	{
		pRtm->SetRenderTarget(pGraphics->getBackBuffer(), 0);
		pRtm->Apply();
		pGraphics->Begin();
		pGraphics->ClearBackBuffer(VectorHelper::vector_4::blue);
		pGraphics->ClearDepthBuffer(1.f);
		sMachine->getCurrentState()->Draw();
		pGraphics->End();
	}
	else
	{
		pGraphics->Begin();
		pGraphics->ClearBackBuffer(VectorHelper::vector_4::blue);
		pGraphics->ClearDepthBuffer(1.f);
		Console::GetInstance()->Draw();
		pGraphics->End();
	}
}

/*static*/ Game* Game::GetInstance(void)
{
	assert(instance && "No game has been inilitized");

	return instance;
}